package com.sinping.qh.repository.mongo.records.impl;

import com.google.common.collect.Lists;
import com.sinping.qh.api.support.ConstEum;
import com.sinping.qh.dto.common.CommonParamDTO;
import com.sinping.qh.repository.mongo.records.HiddenDangerRecordRepository;
import com.sinping.qh.service.common.CommonDbConst;
import com.sinping.qh.utils.time.DateFormatUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * @author zhangjin
 * @create 2018/8/14
 */
@Service
public class HiddenDangerRepositoryImpl {

    @Autowired
    HiddenDangerRecordRepository hiddenDangerRecordRepository;

    @Autowired
    private MongoTemplate template;


    /**
     * 统计未删除隐患的数量
     * @return
     */
    public <T> List<T> findHiddenDangerCount(CommonParamDTO commonParamDTO,String checkItemKey, List<String> groupList, Class<?> clazz, Class<T> target)
    {
        //状态为”已审核“的检查记录中的隐患记录；显示的检查项状态都为“有效“
        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");

        if(StringUtils.isNotBlank(commonParamDTO.getUnitId())){
            criteria.and("check_unit_id").is(commonParamDTO.getUnitId());
        }
        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        operations.add(Aggregation.match(criteria));

        LookupOperation lookupOperation =LookupOperation.newLookup().from("tb_lab_inspect_item_tree")
                .localField(checkItemKey)
                .foreignField("_id")
                .as("inspectItem");
        operations.add(lookupOperation);

        Criteria inspectItem=Criteria.where("inspectItem").ne(new HashSet<>())
                .and("inspectItem.status").is(CommonDbConst.DB_DELETE_NORMAL);
        Criteria one=Criteria.where(checkItemKey).is("");
        Criteria mainCriteria =new Criteria();
        mainCriteria.orOperator(inspectItem,one);

        operations.add(Aggregation.match(mainCriteria));

        if(groupList.size()>0) {
            GroupOperation group = Aggregation.group(groupList.toArray(new String[groupList.size()]));
            group = group.count().as("checkCount");
            operations.add(group);
        }


        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }

    /**
     * 统计已删除检查项隐患的数量
     * @return
     */
    public <T> List<T> findInspectItemDeleteCount(CommonParamDTO commonParamDTO,Class<?> clazz, Class<T> target)
    {
        //状态为”已审核“的检查记录中的隐患记录；显示的检查项状态都为“有效“
        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");

        if(StringUtils.isNotBlank(commonParamDTO.getUnitId())){
            criteria.and("check_unit_id").is(commonParamDTO.getUnitId());
        }
        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }
        operations.add(Aggregation.match(criteria));

        LookupOperation lookupOperation =LookupOperation.newLookup().from("tb_lab_inspect_item_tree")
                .localField("check_item_one_id")
                .foreignField("_id")
                .as("inspectItem");
        operations.add(lookupOperation);

        Criteria inspectItem=Criteria.where("inspectItem.status").is(CommonDbConst.DB_DELETE_LOGICAL);
        operations.add(Aggregation.match(inspectItem));



        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }


    /**
     * 统计隐患的院系分布数
     * @return
     */
    public <T> List<T> findHiddenDangerUnitCount(CommonParamDTO commonParamDTO,String checkItemKey,String checkItemId,
                                                 List<String> groupList, Class<?> clazz, Class<T> target)
    {

        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");

        criteria.and(checkItemKey).is(checkItemId);

        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        operations.add(Aggregation.match(criteria));


        LookupOperation lookupOperation =LookupOperation.newLookup().from("tb_unit")
                .localField("check_unit_id")
                .foreignField("_id")
                .as("unitItem");
        operations.add(lookupOperation);

        Criteria inspectItem=Criteria.where("unitItem").ne(new HashSet<>())
                .and("unitItem.status").is(CommonDbConst.DB_DELETE_NORMAL);

        operations.add(Aggregation.match(inspectItem));
        if(groupList.size()>0) {
            GroupOperation group = Aggregation.group(groupList.toArray(new String[groupList.size()]));
            group = group.count().as("checkCount");
            operations.add(group);
        }


        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }


    /**
     * 统计已删除检查项隐患的院系分布数
     * @return
     */
    public <T> List<T> findHiddenDangerDeleteUnitCount(CommonParamDTO commonParamDTO,
                                                       List<String> groupList, Class<?> clazz, Class<T> target)
    {

        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");
        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        operations.add(Aggregation.match(criteria));

        LookupOperation lookupOperation =LookupOperation.newLookup().from("tb_lab_inspect_item_tree")
                .localField("check_item_one_id")
                .foreignField("_id")
                .as("inspectItem");
        operations.add(lookupOperation);

        Criteria inspectItem=Criteria.where("inspectItem.status").is(CommonDbConst.DB_DELETE_LOGICAL);

        Criteria one=Criteria.where("check_item_one_id").is("");
        Criteria mainCriteria =new Criteria();
        mainCriteria.orOperator(inspectItem,one);
        operations.add(Aggregation.match(mainCriteria));

        LookupOperation lookupOperationUnit =LookupOperation.newLookup().from("tb_unit")
                .localField("check_unit_id")
                .foreignField("_id")
                .as("unitItem");
        operations.add(lookupOperationUnit);

        Criteria unitItem=Criteria.where("unitItem").ne(new HashSet<>())
                .and("unitItem.status").is(CommonDbConst.DB_DELETE_NORMAL);

        operations.add(Aggregation.match(unitItem));
        if(groupList.size()>0) {
            GroupOperation group = Aggregation.group(groupList.toArray(new String[groupList.size()]));
            group = group.count().as("checkCount");
            operations.add(group);
        }


        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }


    /**
     *    查询检查项一级,并且已经整改的隐患
     * @return
     */
    public <T> List<T> findHiddenDangerByCheckItemIdAndHiddenDangerStatus
        (CommonParamDTO commonParamDTO,String checkItemOneId,Class<?> clazz, Class<T> target)
    {

        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");
        if(StringUtils.isNotBlank(checkItemOneId)) {
            criteria.and("check_item_one_id").is(checkItemOneId);
        }else
        {
            criteria.and("check_item_one_id").is("");
        }
        criteria.and("hidden_danger_status").is(CommonDbConst.HIDDENDANGER_STATUS_CLOSE);
        if(StringUtils.isNotBlank(commonParamDTO.getUnitId())){
            criteria.and("check_unit_id").is(commonParamDTO.getUnitId());
        }

        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }
        operations.add(Aggregation.match(criteria));

        if(StringUtils.isNotBlank(checkItemOneId)) {
            LookupOperation lookupOperation = LookupOperation.newLookup().from("tb_lab_inspect_item_tree")
                    .localField("check_item_one_id")
                    .foreignField("_id")
                    .as("inspectItem");
            operations.add(lookupOperation);

            Criteria inspectItem = Criteria.where("inspectItem").ne(new HashSet<>())
                    .and("inspectItem.status").is(CommonDbConst.DB_DELETE_NORMAL);
            operations.add(Aggregation.match(inspectItem));
        }



        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }
    /**
     *    查询检查项一级,所有已经整改的隐患
     * @return
     */
    public <T> List<T> findAHiddenDangerByCheckItemIdAndHiddenDangerStatus
    (CommonParamDTO commonParamDTO,String checkItemOneId,Class<?> clazz, Class<T> target)
    {

        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");
        criteria.and("hidden_danger_status").is(CommonDbConst.HIDDENDANGER_STATUS_CLOSE);

        if(StringUtils.isNotBlank(commonParamDTO.getUnitId())){
            criteria.and("check_unit_id").is(commonParamDTO.getUnitId());
        }

        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }
        operations.add(Aggregation.match(criteria));


        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }

    /**
     *    查询检查项一级,删除的已经整改的隐患
     * @return
     */
    public <T> List<T> findDelteHiddenDangerByCheckItemIdAndHiddenDangerStatus
    (CommonParamDTO commonParamDTO,String checkItemOneId,Class<?> clazz, Class<T> target)
    {

        List<AggregationOperation> operations = Lists.newArrayList();
        Criteria criteria =Criteria.where("check_status").is("3");
        criteria.and("check_item_one_id").ne("");
        criteria.and("hidden_danger_status").is(CommonDbConst.HIDDENDANGER_STATUS_CLOSE);

        if(StringUtils.isNotBlank(commonParamDTO.getUnitId())){
            criteria.and("check_unit_id").is(commonParamDTO.getUnitId());
        }

        if(commonParamDTO.getStartDate()!=null
                && commonParamDTO.getEndDate()!=null){
            try {
                String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                        commonParamDTO.getStartDate());
                String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                        commonParamDTO.getEndDate());

                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        startDate);
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        endDate);
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }

        if(commonParamDTO.getStartYear()!=null
                && commonParamDTO.getEndYear()!=null){
            try {
                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getStartYear()+"-01-01 00:00:00");
                Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                        commonParamDTO.getEndYear()+"-12-31 23:59:59");
                criteria.and("check_date").gte(newStartDate).lte(newEndDate);
            }catch (Exception e){

            }
        }
        operations.add(Aggregation.match(criteria));

        LookupOperation lookupOperation = LookupOperation.newLookup().from("tb_lab_inspect_item_tree")
                .localField("check_item_one_id")
                .foreignField("_id")
                .as("inspectItem");
        operations.add(lookupOperation);

        Criteria inspectItem = Criteria.where("inspectItem.status").is(CommonDbConst.DB_DELETE_LOGICAL);
        operations.add(Aggregation.match(inspectItem));



        Aggregation aggregation  = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, target);
        return results.getMappedResults();
    }
}
